Material Design এবং Custom Views

Mobile App Development - অ্যান্ড্রয়েড ডেভেলপমেন্ট (Android)
327

Material Design হল Google এর ডিজাইন ভাষা যা Android অ্যাপ্লিকেশনগুলিতে একটি সুন্দর, নির্ভুল, এবং ব্যবহারকারীর জন্য মনোমুগ্ধকর UI তৈরি করতে সাহায্য করে। এটি বিভিন্ন UI কম্পোনেন্ট এবং প্রিন্সিপল প্রদান করে, যা অ্যাপ্লিকেশনের UI কনসিস্টেন্ট এবং কার্যকরী করে তোলে। অন্যদিকে, Custom Views ব্যবহার করে আপনি আপনার অ্যাপ্লিকেশনে অনন্য এবং কাস্টমাইজড UI এলিমেন্ট তৈরি করতে পারেন।

Material Design এবং Custom Views

নিচে Material Design এবং Custom Views নিয়ে বিস্তারিত আলোচনা এবং উদাহরণ দেওয়া হলো:


১. Material Design: প্রিন্সিপল এবং কম্পোনেন্টস

Material Design এর মূল লক্ষ্য হল একটি সহজ, আকর্ষণীয়, এবং সুনির্দিষ্ট ব্যবহারকারীর অভিজ্ঞতা তৈরি করা। এর প্রধান প্রিন্সিপল গুলো হল:

  • Surfaces and Shadows: Elevation এবং Z-axis ব্যবহার করে বিভিন্ন UI এলিমেন্টের গভীরতা নির্দেশ করে।
  • Bold Colors and Typography: রঙ এবং ফন্ট ব্যবহারের মাধ্যমে UI কে আরও আকর্ষণীয় এবং রিডেবল করা।
  • Animation and Transitions: UI ইন্টারঅ্যাকশনগুলিকে স্মুথ এবং প্রাকৃতিক করে তুলতে এনিমেশন এবং ট্রানজিশন ব্যবহার করা।

Material Design এর কিছু গুরুত্বপূর্ণ কম্পোনেন্টস:

  • Buttons (Elevated, Flat, Icon)
  • Text Fields (Editable Input Fields)
  • Cards (Information Containers)
  • App Bars (Top and Bottom App Bars)
  • FABs (Floating Action Buttons)
  • Navigation Components (Bottom Navigation, Navigation Drawer)

২. Material Components লাইব্রেরি যোগ করা

Material Design কম্পোনেন্টস ব্যবহার করার জন্য Gradle ফাইলে Material Components লাইব্রেরি যোগ করুন:

implementation 'com.google.android.material:material:1.8.0'

৩. Material Design কম্পোনেন্টস ব্যবহার করা

Material Design এর বিভিন্ন কম্পোনেন্টস XML লেআউট ফাইলে যুক্ত করা যায়।

উদাহরণ: Material Button

<com.google.android.material.button.MaterialButton
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Click Me"
    style="@style/Widget.MaterialComponents.Button" />

উদাহরণ: Floating Action Button (FAB)

<com.google.android.material.floatingactionbutton.FloatingActionButton
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:src="@drawable/ic_add"
    android:contentDescription="Add Item"
    app:backgroundTint="@color/primaryColor"
    app:fabSize="normal" />

উদাহরণ: TextInputLayout এবং TextInputEditText

<com.google.android.material.textfield.TextInputLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:hint="Enter your name">

    <com.google.android.material.textfield.TextInputEditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
</com.google.android.material.textfield.TextInputLayout>

এখানে TextInputLayout এবং TextInputEditText ব্যবহার করে Material Design এর স্টাইল অনুসরণ করে একটি ইনপুট ফিল্ড তৈরি করা হয়েছে।


৪. Material Theme সেটআপ করা

Material Design কম্পোনেন্টস ব্যবহার করার জন্য আপনার অ্যাপ্লিকেশনের থিম Material Design এর সাথে সামঞ্জস্যপূর্ণ হতে হবে। styles.xml এ Material থিম সেট করুন:

<style name="AppTheme" parent="Theme.MaterialComponents.Light.DarkActionBar">
    <!-- Primary branding color -->
    <item name="colorPrimary">@color/primaryColor</item>
    <item name="colorPrimaryVariant">@color/primaryVariant</item>
    <item name="colorOnPrimary">@color/onPrimary</item>
    <!-- Secondary branding color -->
    <item name="colorSecondary">@color/secondaryColor</item>
    <item name="colorSecondaryVariant">@color/secondaryVariant</item>
    <item name="colorOnSecondary">@color/onSecondary</item>
</style>

Material Components থিম ব্যবহার করে অ্যাপ্লিকেশনের রঙ এবং স্টাইল কাস্টমাইজ করা যায়।


৫. Custom Views তৈরি করা

Custom Views ব্যবহার করে আপনি আপনার অ্যাপ্লিকেশনে অনন্য এবং সম্পূর্ণ কাস্টম UI এলিমেন্ট তৈরি করতে পারেন। এটি বিশেষ করে তখন ব্যবহৃত হয়, যখন Material Design এর বিদ্যমান কম্পোনেন্টস অ্যাপ্লিকেশনের প্রয়োজন পূরণ করে না।

উদাহরণ: Simple Custom View তৈরি করা

class CustomCircleView @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr) {

    private val paint = Paint().apply {
        color = Color.BLUE
        style = Paint.Style.FILL
    }

    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)
        // কেন্দ্র নির্ধারণ
        val radius = min(width, height) / 2f
        val cx = width / 2f
        val cy = height / 2f
        canvas.drawCircle(cx, cy, radius, paint)
    }
}

XML এ Custom View ব্যবহার করা

<com.example.customviews.CustomCircleView
    android:layout_width="100dp"
    android:layout_height="100dp" />

এখানে CustomCircleView একটি কাস্টম ভিউ, যা একটি নীল বৃত্ত আঁকে। onDraw() মেথড ওভাররাইড করে আমরা কাস্টমাইজড গ্রাফিক্স অঙ্কন করেছি।


৬. Custom Attributes যোগ করা

আপনার Custom View আরও ফ্লেক্সিবল করতে, আপনি XML এ কাস্টম অ্যাট্রিবিউট যোগ করতে পারেন।

উদাহরণ: কাস্টম অ্যাট্রিবিউট যোগ করা

attrs.xml এ কাস্টম অ্যাট্রিবিউট ডিফাইন করুন:

<declare-styleable name="CustomCircleView">
    <attr name="circleColor" format="color" />
    <attr name="circleRadius" format="dimension" />
</declare-styleable>

Custom View ক্লাসে কাস্টম অ্যাট্রিবিউট ব্যবহার করা

class CustomCircleView @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr) {

    private var circleColor = Color.BLUE
    private var circleRadius = 50f

    init {
        context.theme.obtainStyledAttributes(attrs, R.styleable.CustomCircleView, 0, 0).apply {
            try {
                circleColor = getColor(R.styleable.CustomCircleView_circleColor, Color.BLUE)
                circleRadius = getDimension(R.styleable.CustomCircleView_circleRadius, 50f)
            } finally {
                recycle()
            }
        }
    }

    private val paint = Paint().apply {
        color = circleColor
        style = Paint.Style.FILL
    }

    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)
        val cx = width / 2f
        val cy = height / 2f
        canvas.drawCircle(cx, cy, circleRadius, paint)
    }
}

XML এ Custom Attributes ব্যবহার করা

<com.example.customviews.CustomCircleView
    android:layout_width="100dp"
    android:layout_height="100dp"
    app:circleColor="@android:color/holo_red_dark"
    app:circleRadius="40dp" />

এখানে, CustomCircleView এ আমরা circleColor এবং circleRadius অ্যাট্রিবিউট যোগ করেছি, যা XML এ কাস্টমাইজ করা যায়।


৭. Material Animations এবং Transitions

Material Design এর অংশ হিসেবে, অ্যাপ্লিকেশনে স্মুথ ট্রানজিশন এবং এনিমেশন যোগ করা যায়, যা UI ইন্টারঅ্যাকশনকে আরও প্রাকৃতিক এবং ব্যবহারবান্ধব করে তোলে।

উদাহরণ: Button ক্লিক এনিমেশন

val scaleX = ObjectAnimator.ofFloat(button, "scaleX", 1f, 1.1f, 1f)
val scaleY = ObjectAnimator.ofFloat(button, "scaleY", 1f, 1.1f, 1f)
val animatorSet = AnimatorSet()
animatorSet.playTogether(scaleX, scaleY)
animatorSet.duration = 300
animatorSet.start()

এই উদাহরণে, বাটনের ক্লিক ইভেন্টে একটি স্কেল এনিমেশন যোগ করা হয়েছে।


উপসংহার

Material Design এবং Custom Views ব্যবহার করে Android অ্যাপ্লিকেশনগুলিকে আরও আকর্ষণীয়, ব্যবহারবান্ধব, এবং কাস্টমাইজড করা যায়। Material Components এর মাধ্যমে সহজেই কনসিস্টেন্ট UI তৈরি করা যায় এবং Custom Views ব্যবহার করে অনন্য ডিজাইন এবং ফিচার যুক্ত করা যায়। সঠিক থিম এবং স্টাইল ব্যবহারের মাধ্যমে, আপনার অ্যাপ্লিকেশনকে একটি প্রফেশনাল এবং ইউনিক লুক দেওয়া সম্ভব।

Content added By

Material Design এর ধারণা এবং Components

400

Material Design এর ধারণা এবং Components

Material Design হল Google দ্বারা প্রস্তাবিত একটি ডিজাইন ভাষা, যা ব্যবহারকারীর ইন্টারফেস এবং ইন্টারঅ্যাকশন ডিজাইন করার জন্য একটি স্ট্যান্ডার্ড পদ্ধতি প্রদান করে। এটি মূলত Android অ্যাপ্লিকেশনগুলির জন্য ডিজাইন করা হয়েছে, তবে এটি ওয়েব এবং অন্যান্য প্ল্যাটফর্মেও ব্যবহৃত হয়। Material Design এর লক্ষ্য হল একটি সুনির্দিষ্ট, পরিষ্কার, এবং ইন্টারঅ্যাকটিভ ডিজাইন পরিবেশ তৈরি করা, যা ইউজারকে সহজে অ্যাপ্লিকেশনের সাথে ইন্টারঅ্যাক্ট করতে সাহায্য করে।


Material Design এর ধারণা

Material Metaphor: Material Design এর মূল ধারণা হল বাস্তব জগতের উপাদানগুলোর অনুকরণ। এটি UI উপাদানগুলোকে এমনভাবে ডিজাইন করে যেন তারা বাস্তব উপকরণ, যেমন কাগজ বা কার্ডবোর্ডের মতো অনুভূতি প্রদান করে। এ কারণে, UI উপাদানগুলোতে ছায়া, প্রান্ত, এবং অ্যানিমেশন ব্যবহার করে গভীরতা এবং বাস্তবিক ইন্টারফেস তৈরি করা হয়।

Bold, Graphic, Intentional: Material Design এ উজ্জ্বল রঙ, বড় টেক্সট, এবং গ্রাফিক্যাল উপাদান ব্যবহার করা হয়, যাতে UI আরো আকর্ষণীয় এবং সহজবোধ্য হয়। এর মাধ্যমে ইউজার অ্যাকশন এবং কনটেন্টকে সুনির্দিষ্টভাবে উপস্থাপন করা যায়।

Motion Provides Meaning: অ্যানিমেশন এবং মোশন Material Design এর একটি গুরুত্বপূর্ণ অংশ। মোশন ইফেক্ট ব্যবহার করে UI ইন্টারঅ্যাকশনের সময় প্রয়োজনীয় ফিডব্যাক প্রদান করা হয় এবং অ্যাপ্লিকেশনের বিভিন্ন উপাদানের সম্পর্ক বোঝানো হয়। এটি ইউজার ইন্টারফেসকে প্রাকৃতিক এবং ইন্টারঅ্যাকটিভ করে তোলে।


Material Design এর প্রধান Components

Material Design বিভিন্ন ধরনের UI কম্পোনেন্ট প্রদান করে, যা অ্যাপ্লিকেশনের ডিজাইন এবং কার্যকারিতা উন্নত করতে ব্যবহৃত হয়। কিছু প্রধান Material Design কম্পোনেন্ট নিচে উল্লেখ করা হলো:

১. App Bar (Toolbar)

App Bar বা Toolbar হল একটি প্রধান UI উপাদান, যা অ্যাপের টাইটেল, নেভিগেশন ড্রয়ার, এবং অ্যাকশন আইটেম প্রদর্শন করে। এটি অ্যাপ্লিকেশনের বিভিন্ন স্ক্রিনে নেভিগেট করতে এবং ইউজারকে কন্টেক্সট প্রদান করতে সহায়ক।

<androidx.appcompat.widget.Toolbar
    android:id="@+id/toolbar"
    android:layout_width="match_parent"
    android:layout_height="?attr/actionBarSize"
    android:background="?attr/colorPrimary"
    android:theme="@style/ThemeOverlay.AppCompat.ActionBar"/>

২. Floating Action Button (FAB)

Floating Action Button একটি রাউন্ড বাটন, যা একটি প্রধান অ্যাকশন বা টাস্ক প্রদর্শন করতে ব্যবহৃত হয়। এটি সাধারণত স্ক্রিনের নিচের দিকে থাকে এবং প্রধান অ্যাকশনকে হাইলাইট করতে ব্যবহৃত হয়।

<com.google.android.material.floatingactionbutton.FloatingActionButton
    android:id="@+id/fab"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="end|bottom"
    android:src="@drawable/ic_add"
    app:backgroundTint="@color/colorAccent"/>

৩. CardView

CardView একটি Material Design কার্ড উপাদান, যা কনটেন্ট গ্রুপ করতে এবং প্রেজেন্টেশনের জন্য ব্যবহৃত হয়। এটি ছায়া এবং প্রান্ত ব্যবহার করে একটি গভীরতা প্রদান করে, যা UI কে বাস্তবিক এবং ইন্টারঅ্যাকটিভ করে তোলে।

<androidx.cardview.widget.CardView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:cardCornerRadius="8dp"
    app:cardElevation="4dp">
    <!-- কনটেন্ট -->
</androidx.cardview.widget.CardView>

৪. Bottom Navigation

Bottom Navigation কম্পোনেন্ট নেভিগেশন আইটেম প্রদর্শন করে এবং স্ক্রিনের নিচে থাকে। এটি সাধারণত ৩ থেকে ৫টি প্রধান স্ক্রিনের মধ্যে নেভিগেট করতে ব্যবহার করা হয়।

<com.google.android.material.bottomnavigation.BottomNavigationView
    android:id="@+id/bottom_navigation"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_gravity="bottom"
    app:menu="@menu/bottom_nav_menu"/>

৫. Snackbars এবং Toasts

Snackbars এবং Toasts হল অস্থায়ী নোটিফিকেশন উপাদান, যা ইউজারকে কিছু তথ্য বা অ্যালার্ট প্রদর্শন করে। Snackbar Material Design এর একটি উপাদান, যা স্ক্রিনের নিচে প্রদর্শিত হয় এবং সাময়িক সময়ের জন্য থাকে।

Snackbar.make(view, "Action completed", Snackbar.LENGTH_SHORT).show();

৬. TextInputLayout

TextInputLayout হল Material Design এর একটি ইনপুট ফিল্ড, যা হিন্ট এবং এরর মেসেজের জন্য অ্যাডভান্সড স্টাইল প্রদান করে। এটি ব্যবহার করে ইনপুট ফিল্ডের ডিজাইন উন্নত করা যায়।

<com.google.android.material.textfield.TextInputLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <com.google.android.material.textfield.TextInputEditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="Enter your name"/>

</com.google.android.material.textfield.TextInputLayout>

৭. RecyclerView

RecyclerView হল একটি শক্তিশালী UI উপাদান, যা একটি বড় ডেটা সেট ডিসপ্লে করতে সাহায্য করে। এটি Material Design এর একটি লিস্ট বা গ্রিড ফরম্যাটে ডেটা প্রদর্শন করার জন্য আদর্শ উপায়।

<androidx.recyclerview.widget.RecyclerView
    android:id="@+id/recyclerView"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layoutManager="LinearLayoutManager"/>

Material Design এর সুবিধা

সুবিধাবিস্তারিত
Consistencyঅ্যাপ্লিকেশনের ইন্টারফেস একসাথে মানানসই হয়।
Responsive Designবিভিন্ন ডিভাইস এবং স্ক্রিন সাইজের সাথে সাপোর্ট করে।
Access to ComponentsMaterial Design এর UI উপাদানগুলো সহজেই ব্যবহৃত হয়।
Modern Look and Feelঅ্যাপ্লিকেশনের ইউজার ইন্টারফেসকে আধুনিক এবং আকর্ষণীয় করে তোলে।
Accessibilityঅ্যাপ্লিকেশনের এক্সেসিবিলিটি উন্নত করে।

উপসংহার

Material Design Android অ্যাপ্লিকেশন ডেভেলপমেন্টের জন্য একটি স্ট্যান্ডার্ড এবং প্রফেশনাল ডিজাইন প্যাটার্ন প্রদান করে। এর বিভিন্ন কম্পোনেন্ট এবং গাইডলাইন ব্যবহার করে একটি অ্যাপ্লিকেশনকে আরও ইন্টারঅ্যাকটিভ, ব্যবহারবান্ধব এবং আধুনিক করা যায়। Material Design এর সঠিক ব্যবহার অ্যাপের কার্যকারিতা এবং ইউজার এক্সপেরিয়েন্স উন্নত করতে সাহায্য করে।

Content added By

Toolbar, Floating Action Button (FAB), এবং Navigation Drawer

388

Toolbar, Floating Action Button (FAB), এবং Navigation Drawer হল Android অ্যাপ্লিকেশন ইন্টারফেসের সাধারণ উপাদান, যা অ্যাপ্লিকেশনকে ব্যবহারকারী বান্ধব এবং ইন্টারেক্টিভ করে তোলে। এগুলো ব্যবহার করে আপনি অ্যাপ্লিকেশনের ইউজার ইন্টারফেসে কার্যকরী এবং নেভিগেশন ফিচার যোগ করতে পারেন। 

Toolbar, Floating Action Button (FAB), এবং Navigation Drawer

নিচে প্রত্যেকটি উপাদান নিয়ে বিস্তারিত আলোচনা এবং উদাহরণ দেওয়া হয়েছে।


১. Toolbar

Toolbar হল Android অ্যাপ্লিকেশনের একটি উপাদান, যা সাধারণত অ্যাপের উপরের দিকে থাকে এবং এতে টাইটেল, মেনু আইটেম, সার্চ বার, এবং অন্যান্য একশন বা আইকন দেখা যায়। এটি ActionBar এর একটি কাস্টমাইজেবল সংস্করণ।

Toolbar সেটআপ করা

Gradle ফাইলে Material Components ডিপেনডেন্সি যোগ করুন:

implementation 'com.google.android.material:material:1.9.0'

XML এ Toolbar যোগ করা

<com.google.android.material.appbar.MaterialToolbar
    android:id="@+id/toolbar"
    android:layout_width="match_parent"
    android:layout_height="?attr/actionBarSize"
    android:background="?attr/colorPrimary"
    app:title="My Toolbar"
    app:titleTextColor="@android:color/white"/>

Activity এ Toolbar সেটআপ করা

import androidx.appcompat.widget.Toolbar;

Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);

এখানে MaterialToolbar ব্যবহার করে একটি কাস্টম Toolbar সেটআপ করা হয়েছে। setSupportActionBar() মেথড ব্যবহার করে এটিকে অ্যাপের ActionBar হিসেবে সেট করা হয়েছে।


২. Floating Action Button (FAB)

Floating Action Button (FAB) হল একটি সোজাসাপ্টা, গোলাকার বোতাম যা অ্যাপ্লিকেশনের স্ক্রিনের উপর ভেসে থাকে এবং সাধারণত একটি প্রাইমারি অ্যাকশন সম্পাদনের জন্য ব্যবহৃত হয়। এটি Material Design এর একটি অংশ।

XML এ FAB যোগ করা

<com.google.android.material.floatingactionbutton.FloatingActionButton
    android:id="@+id/fab"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="bottom|end"
    android:layout_margin="16dp"
    android:src="@drawable/ic_add"
    android:contentDescription="Add"
    app:backgroundTint="@color/colorAccent"/>

এখানে FloatingActionButton ব্যবহার করে একটি FAB যোগ করা হয়েছে। এটি bottom|end পজিশনে রাখা হয়েছে যাতে এটি স্ক্রিনের নিচের ডানদিকে প্রদর্শিত হয়।

FAB এর ক্লিক ইভেন্ট হ্যান্ডল করা

FloatingActionButton fab = findViewById(R.id.fab);
fab.setOnClickListener(view -> {
    // FAB ক্লিক করার সময় করণীয় কাজ
    Snackbar.make(view, "FAB clicked!", Snackbar.LENGTH_LONG).show();
});

এখানে FloatingActionButton এর setOnClickListener() মেথড ব্যবহার করে ক্লিক ইভেন্ট হ্যান্ডল করা হয়েছে। Snackbar ব্যবহার করে একটি মেসেজ প্রদর্শন করা হয়েছে।


৩. Navigation Drawer

Navigation Drawer হল একটি ড্রয়ার বা সাইড মেনু, যা স্ক্রিনের বাঁ দিক থেকে স্লাইড করে আসে এবং ব্যবহারকারীকে অ্যাপ্লিকেশনের বিভিন্ন অংশে নেভিগেট করতে সাহায্য করে। এটি সাধারণত DrawerLayout এবং NavigationView ব্যবহার করে তৈরি করা হয়।

Step 1: XML এ DrawerLayout এবং NavigationView যোগ করা

<androidx.drawerlayout.widget.DrawerLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <com.google.android.material.appbar.MaterialToolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            app:title="My App"
            app:titleTextColor="@android:color/white"/>

        <!-- Content area -->
        <FrameLayout
            android:id="@+id/content_frame"
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>
    </LinearLayout>

    <com.google.android.material.navigation.NavigationView
        android:id="@+id/nav_view"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        app:menu="@menu/drawer_menu"/>
</androidx.drawerlayout.widget.DrawerLayout>

এখানে DrawerLayout এর ভেতরে একটি NavigationView যোগ করা হয়েছে। app

অ্যাট্রিবিউটের মাধ্যমে একটি মেনু রিসোর্স সেট করা হয়েছে, যা ড্রয়ারে প্রদর্শিত হবে।

 

Step 2: Menu Resource (drawer_menu.xml) তৈরি করা

<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:id="@+id/nav_home"
        android:title="Home"
        android:icon="@drawable/ic_home"/>
    <item
        android:id="@+id/nav_settings"
        android:title="Settings"
        android:icon="@drawable/ic_settings"/>
</menu>

res/menu ডিরেক্টরিতে drawer_menu.xml ফাইল তৈরি করে মেনু আইটেম যোগ করা হয়েছে।

Step 3: Activity এ Navigation Drawer সেটআপ করা

import androidx.appcompat.app.ActionBarDrawerToggle;
import androidx.drawerlayout.widget.DrawerLayout;
import com.google.android.material.navigation.NavigationView;

DrawerLayout drawerLayout = findViewById(R.id.drawer_layout);
NavigationView navigationView = findViewById(R.id.nav_view);
Toolbar toolbar = findViewById(R.id.toolbar);

setSupportActionBar(toolbar);

// Drawer টগল বাটন সেটআপ করা
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
        this, drawerLayout, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawerLayout.addDrawerListener(toggle);
toggle.syncState();

// মেনু আইটেম ক্লিক ইভেন্ট হ্যান্ডল করা
navigationView.setNavigationItemSelectedListener(item -> {
    switch (item.getItemId()) {
        case R.id.nav_home:
            // Home এ নেভিগেট করা
            break;
        case R.id.nav_settings:
            // Settings এ নেভিগেট করা
            break;
    }
    drawerLayout.closeDrawer(GravityCompat.START);
    return true;
});

এখানে ActionBarDrawerToggle ব্যবহার করে ড্রয়ার টগল সেটআপ করা হয়েছে, যাতে Toolbar এর টগল বাটন ক্লিক করলে ড্রয়ার খোলে বা বন্ধ হয়। setNavigationItemSelectedListener() মেথডের মাধ্যমে মেনু আইটেমের ক্লিক ইভেন্ট হ্যান্ডল করা হয়েছে।


৪. Toolbar, FAB, এবং Navigation Drawer একত্রে ব্যবহারের উদাহরণ

নিচে একটি সাধারণ উদাহরণ দেখানো হয়েছে যেখানে একটি অ্যাপ্লিকেশনে Toolbar, FAB, এবং Navigation Drawer একত্রে ব্যবহার করা হয়েছে।

<androidx.drawerlayout.widget.DrawerLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <com.google.android.material.appbar.MaterialToolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            app:title="My App"/>

        <FrameLayout
            android:id="@+id/content_frame"
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>
            
        <com.google.android.material.floatingactionbutton.FloatingActionButton
            android:id="@+id/fab"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="bottom|end"
            android:layout_margin="16dp"
            android:src="@drawable/ic_add"/>
    </LinearLayout>

    <com.google.android.material.navigation.NavigationView
        android:id="@+id/nav_view"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        app:menu="@menu/drawer_menu"/>
</androidx.drawerlayout.widget.DrawerLayout>

এই উদাহরণে, Toolbar, FloatingActionButton, এবং NavigationView একত্রে ব্যবহৃত হয়েছে। এটি একটি সাধারণ Layout যেখানে আপনি একটি অ্যাপ্লিকেশনকে আরও কার্যকরী এবং ইন্টারেক্টিভ করে তুলতে পারেন।


উপসংহার

Toolbar, Floating Action Button (FAB), এবং Navigation Drawer Android অ্যাপ্লিকেশনের ইন্টারফেসে কার্যকরী এবং ব্যবহারকারী বান্ধব উপাদান যোগ করতে অত্যন্ত গুরুত্বপূর্ণ।

  • Toolbar অ্যাপ্লিকেশনের শিরোনাম, মেনু আইটেম, এবং অ্যাকশনগুলি প্রদর্শন করার একটি কাস্টমাইজেবল উপায় প্রদান করে, যা অ্যাপ্লিকেশনের পরিচ্ছন্ন এবং সুসংহত লেআউট নিশ্চিত করে।
  • Floating Action Button (FAB) ব্যবহার করে প্রাইমারি অ্যাকশন বা গুরুত্বপূর্ণ কাজগুলি দ্রুত অ্যাক্সেস করা যায়। এটি একটি সহজবোধ্য এবং আকর্ষণীয় উপাদান যা Material Design এর অংশ।
  • Navigation Drawer ব্যবহার করে অ্যাপ্লিকেশনে বিভিন্ন অংশ বা স্ক্রিনে নেভিগেট করা সহজ হয়। এটি বিশেষ করে বড় অ্যাপ্লিকেশনগুলির জন্য উপযুক্ত, যেখানে অনেকগুলো সেকশন বা ফিচার থাকে।

এই উপাদানগুলির সঠিক এবং সৃজনশীল ব্যবহারের মাধ্যমে Android অ্যাপ্লিকেশনকে আরও ব্যবহারকারী বান্ধব, কার্যকরী, এবং আকর্ষণীয় করে তোলা সম্ভব। অ্যাপ্লিকেশনের নেভিগেশন সহজ করতে এবং ব্যবহারকারীর অভিজ্ঞতা উন্নত করতে এই উপাদানগুলো একটি গুরুত্বপূর্ণ ভূমিকা পালন করে।

Content added || updated By

Custom Views তৈরি করা

308

Custom Views তৈরি করা

Android এ Custom Views তৈরি করে, আপনি আপনার অ্যাপ্লিকেশনে অনন্য এবং কাস্টমাইজড UI এলিমেন্ট তৈরি করতে পারেন, যা সাধারণ Material Components দিয়ে সম্ভব নয়। Custom Views ব্যবহার করে আপনি সম্পূর্ণ কাস্টমাইজড গ্রাফিক্স, অ্যানিমেশন, এবং UI উপাদান ডিজাইন করতে পারেন। নিচে Custom Views তৈরি করার ধাপে ধাপে আলোচনা এবং উদাহরণ দেওয়া হলো।


১. Custom View তৈরি করার ধাপসমূহ

Custom View তৈরি করতে কয়েকটি ধাপ অনুসরণ করতে হয়:

  • View বা ViewGroup ক্লাসটি এক্সটেন্ড (extend) করা।
  • onDraw() মেথড ওভাররাইড করে কাস্টম গ্রাফিক্স অঙ্কন করা।
  • Custom Attributes ব্যবহার করে View কে আরও কাস্টমাইজযোগ্য করা।
  • Measure মেথড ব্যবহার করে View এর সঠিক মাপ নির্ধারণ করা।

২. Simple Custom View তৈরি করা

নিচে একটি সিম্পল Custom View তৈরি করা হয়েছে, যা একটি বৃত্ত আঁকে।

CustomCircleView.kt (Kotlin)

package com.example.customviews

import android.content.Context
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.util.AttributeSet
import android.view.View

class CustomCircleView @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr) {

    private val paint = Paint().apply {
        color = Color.BLUE
        style = Paint.Style.FILL
    }

    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)
        // বৃত্তের কেন্দ্র এবং রেডিয়াস নির্ধারণ
        val radius = minOf(width, height) / 2f
        val cx = width / 2f
        val cy = height / 2f
        canvas.drawCircle(cx, cy, radius, paint)
    }
}

XML Layout এ Custom View ব্যবহার করা

<com.example.customviews.CustomCircleView
    android:layout_width="150dp"
    android:layout_height="150dp" />

এই উদাহরণে, CustomCircleView ক্লাসটি View এক্সটেন্ড করেছে এবং onDraw() মেথডে একটি নীল বৃত্ত অঙ্কন করেছে।


৩. Custom Attributes যোগ করা

Custom Attributes যোগ করে আপনি আপনার Custom View কে আরও কাস্টমাইজযোগ্য করতে পারেন। XML এ কাস্টম অ্যাট্রিবিউট ডিফাইন করা এবং View তে এগুলো প্রসেস করা হয়।

ধাপ ১: attrs.xml এ কাস্টম অ্যাট্রিবিউট ডিফাইন করা

<declare-styleable name="CustomCircleView">
    <attr name="circleColor" format="color" />
    <attr name="circleRadius" format="dimension" />
</declare-styleable>

ধাপ ২: Custom View এ কাস্টম অ্যাট্রিবিউট প্রসেস করা

class CustomCircleView @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr) {

    private var circleColor = Color.BLUE
    private var circleRadius = 50f

    init {
        context.theme.obtainStyledAttributes(attrs, R.styleable.CustomCircleView, 0, 0).apply {
            try {
                circleColor = getColor(R.styleable.CustomCircleView_circleColor, Color.BLUE)
                circleRadius = getDimension(R.styleable.CustomCircleView_circleRadius, 50f)
            } finally {
                recycle()
            }
        }
    }

    private val paint = Paint().apply {
        color = circleColor
        style = Paint.Style.FILL
    }

    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)
        val cx = width / 2f
        val cy = height / 2f
        canvas.drawCircle(cx, cy, circleRadius, paint)
    }
}

ধাপ ৩: XML Layout এ Custom Attributes ব্যবহার করা

<com.example.customviews.CustomCircleView
    android:layout_width="200dp"
    android:layout_height="200dp"
    app:circleColor="@android:color/holo_red_dark"
    app:circleRadius="80dp" />

এখানে, circleColor এবং circleRadius অ্যাট্রিবিউট ব্যবহার করে View কে XML থেকে কাস্টমাইজ করা হয়েছে। context.theme.obtainStyledAttributes() ব্যবহার করে অ্যাট্রিবিউট সংগ্রহ করা হয়েছে এবং View এ প্রয়োগ করা হয়েছে।


৪. Custom Measure মেথড ব্যবহার করা

Custom View এর সঠিক মাপ নির্ধারণের জন্য, onMeasure() মেথড ওভাররাইড করা প্রয়োজন হতে পারে। এটি View কে কাস্টম মাপ সেট করতে এবং রিসাইজ করতে সহায়তা করে।

উদাহরণ: Custom Measure মেথড ব্যবহার করা

override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
    val desiredWidth = 200
    val desiredHeight = 200

    val widthMode = MeasureSpec.getMode(widthMeasureSpec)
    val heightMode = MeasureSpec.getMode(heightMeasureSpec)
    val widthSize = MeasureSpec.getSize(widthMeasureSpec)
    val heightSize = MeasureSpec.getSize(heightMeasureSpec)

    val width = when (widthMode) {
        MeasureSpec.EXACTLY -> widthSize
        MeasureSpec.AT_MOST -> minOf(desiredWidth, widthSize)
        MeasureSpec.UNSPECIFIED -> desiredWidth
        else -> desiredWidth
    }

    val height = when (heightMode) {
        MeasureSpec.EXACTLY -> heightSize
        MeasureSpec.AT_MOST -> minOf(desiredHeight, heightSize)
        MeasureSpec.UNSPECIFIED -> desiredHeight
        else -> desiredHeight
    }

    setMeasuredDimension(width, height)
}

onMeasure() মেথডে View এর চাহিদা অনুযায়ী প্রস্থ এবং উচ্চতা নির্ধারণ করা হয়েছে। MeasureSpec ব্যবহার করে, আপনি View এর লেআউট পরিমাপ ম্যানেজ করতে পারেন।


৫. Custom ViewGroup তৈরি করা

কিছু ক্ষেত্রে, একটি কাস্টম লেআউট বা ViewGroup তৈরি করা প্রয়োজন হতে পারে, যা একাধিক Child View কে কাস্টমাইজড ম্যানেজমেন্ট প্রদান করে।

উদাহরণ: Custom ViewGroup তৈরি করা

class CustomLinearLayout @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0
) : ViewGroup(context, attrs, defStyleAttr) {

    override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) {
        var topOffset = 0
        for (i in 0 until childCount) {
            val child = getChildAt(i)
            child.layout(l, topOffset, r, topOffset + child.measuredHeight)
            topOffset += child.measuredHeight
        }
    }

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        var totalHeight = 0
        var maxWidth = 0

        for (i in 0 until childCount) {
            val child = getChildAt(i)
            measureChild(child, widthMeasureSpec, heightMeasureSpec)
            totalHeight += child.measuredHeight
            maxWidth = maxOf(maxWidth, child.measuredWidth)
        }

        setMeasuredDimension(
            resolveSize(maxWidth, widthMeasureSpec),
            resolveSize(totalHeight, heightMeasureSpec)
        )
    }
}

এই উদাহরণে, CustomLinearLayout একটি কাস্টম লিনিয়ার লেআউট তৈরি করেছে, যা Child View গুলিকে উল্লম্বভাবে সাজিয়েছে।


৬. Custom View তে এনিমেশন যোগ করা

Custom View তে এনিমেশন যোগ করে UI কে আরও ইন্টারেক্টিভ করা যায়।

উদাহরণ: Custom View এ এনিমেশন যোগ করা

fun animateCircle() {
    val animator = ValueAnimator.ofFloat(0f, 360f)
    animator.addUpdateListener { animation ->
        rotation = animation.animatedValue as Float
        invalidate()
    }
    animator.duration = 1000
    animator.start()
}

এই উদাহরণে, একটি এনিমেটেড রোটেশন তৈরি করা হয়েছে, যা Custom View তে এনিমেশন যোগ করে।


উপসংহার

Custom Views তৈরি করে, আপনি আপনার অ্যাপ্লিকেশনে সম্পূর্ণ কাস্টমাইজড UI এলিমেন্ট যোগ করতে পারেন, যা সাধারণ Material Components বা বিদ্যমান Views দিয়ে সম্ভব নয়। Custom Attributes, Measure মেথড, এবং এনিমেশন ব্যবহার করে, আপনি আপনার View কে সম্পূর্ণ কাস্টমাইজ করতে এবং একটি উন্নত ব্যবহারকারীর অভিজ্ঞতা প্রদান করতে সক্ষম হবেন।

Content added By

Animations এবং Transitions এর মাধ্যমে UI Enhancement

333

Animations এবং Transitions এর মাধ্যমে UI Enhancement

Animations এবং Transitions Android অ্যাপ্লিকেশনগুলিতে UI উপাদানগুলোর ইন্টারঅ্যাকশন এবং ভিজ্যুয়াল ইফেক্ট উন্নত করতে ব্যবহার করা হয়। এগুলো UI কে আরও আকর্ষণীয় এবং ইন্টারঅ্যাকটিভ করে তোলে, যা ব্যবহারকারীর অভিজ্ঞতাকে উন্নত করতে সহায়ক। Material Design এ অ্যানিমেশন এবং ট্রানজিশন গুরুত্বপূর্ণ ভূমিকা পালন করে, কারণ এটি কন্টেন্ট এবং ইউজারের ইন্টারঅ্যাকশনের মধ্যে একটি সংযোগ তৈরি করে।


Android এ Animations এর ধরন

  1. Property Animations: Property Animations হল Android এর অ্যানিমেশন সিস্টেম, যা ObjectAnimator, ValueAnimator, এবং AnimatorSet ব্যবহার করে UI উপাদানগুলোর প্রপার্টি (যেমন opacity, translation, rotation) পরিবর্তন করে অ্যানিমেশন তৈরি করে।
  2. View Animations: পুরনো অ্যানিমেশন API, যা View এর পরিবর্তন (Scale, Rotate, Translate, Alpha) নির্ধারণ করে।
  3. Drawable Animations: Drawable অ্যানিমেশন ব্যবহার করে একাধিক ইমেজ সিকোয়েন্স তৈরি করা হয়, যা একটি ফ্রেম-বাই-ফ্রেম অ্যানিমেশন তৈরি করে।
  4. MotionLayout: ConstraintLayout এর অংশ, যা Material Design এর সাথে মিল রেখে অ্যানিমেশন পরিচালনা করার জন্য ব্যবহৃত হয়। এটি UI উপাদানগুলোর স্থানান্তর এবং অবস্থান নির্ধারণ করে একটি উন্নত অ্যানিমেশন তৈরি করতে পারে।

Android এ Transitions

Transitions হল একটি Activity বা Fragment থেকে আরেকটিতে যাওয়ার সময় UI উপাদানগুলোর পরিবর্তন। Material Design এ Transitions ব্যবহার করে সহজে Activity এবং Fragment পরিবর্তনের সময় অ্যানিমেশন তৈরি করা যায়।

Transitions এর প্রধান ধরন:

  1. Explode: View উপাদানগুলো স্ক্রিনের কেন্দ্র থেকে বাইরে বা বাইরে থেকে ভিতরে চলে আসে।
  2. Slide: View উপাদানগুলো স্ক্রিনের এক প্রান্ত থেকে অন্য প্রান্তে স্লাইড করে।
  3. Fade: View উপাদানগুলো ধীরে ধীরে দৃশ্যমান বা অদৃশ্য হয়ে যায়।

Example: Property Animation (ObjectAnimator)

Property Animation ব্যবহার করে UI উপাদানগুলোর প্রপার্টি পরিবর্তন করে অ্যানিমেশন তৈরি করা যায়।

activity_main.xml:

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:gravity="center">

    <Button
        android:id="@+id/animateButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Animate"/>

    <ImageView
        android:id="@+id/animatedView"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:src="@drawable/ic_launcher_foreground"/>
</LinearLayout>

MainActivity.java:

import android.animation.ObjectAnimator;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;
import androidx.appcompat.app.AppCompatActivity;

public class MainActivity extends AppCompatActivity {

    private ImageView animatedView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        animatedView = findViewById(R.id.animatedView);
        findViewById(R.id.animateButton).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                ObjectAnimator animator = ObjectAnimator.ofFloat(animatedView, "translationY", 0f, 300f);
                animator.setDuration(500); // ৫০০ মিলিসেকেন্ড সময় নেবে
                animator.start();
            }
        });
    }
}

কোডের ব্যাখ্যা:

  • ObjectAnimator: এটি UI উপাদানের প্রপার্টি (যেমন translationY) এর পরিবর্তন নির্ধারণ করে। setDuration() মেথড দিয়ে অ্যানিমেশনের সময় নির্ধারণ করা হয়েছে।
  • Button: বাটনে ক্লিক করলে অ্যানিমেশন শুরু হয়, যা ImageView কে স্ক্রিনে স্লাইড করে নিয়ে যায়।

Example: Transition Animation

Transition Animation ব্যবহার করে Activity বা Fragment পরিবর্তনের সময় অ্যানিমেশন পরিচালনা করা যায়।

ধাপ ১: Transitions যোগ করা

AndroidManifest.xml এ Activity এর জন্য Transition সেট করা:

<activity android:name=".SecondActivity"
    android:theme="@style/Theme.AppCompat.Light.NoActionBar">
    <meta-data
        android:name="android.support.PARENT_ACTIVITY"
        android:value=".MainActivity" />
</activity>

ধাপ ২: Transition সেটআপ করা

MainActivity.java:

import android.content.Intent;
import android.os.Bundle;
import android.transition.Explode;
import android.transition.Fade;
import android.transition.Slide;
import android.view.View;
import androidx.appcompat.app.AppCompatActivity;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        findViewById(R.id.transitionButton).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // নতুন Activity তে যাওয়ার জন্য Intent
                Intent intent = new Intent(MainActivity.this, SecondActivity.class);

                // Transition সেট করা
                getWindow().setExitTransition(new Slide());
                startActivity(intent, null);
            }
        });
    }
}

ধাপ ৩: SecondActivity এ Transition যোগ করা

SecondActivity.java:

import android.os.Bundle;
import android.transition.Fade;
import androidx.appcompat.app.AppCompatActivity;

public class SecondActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second);

        // Transition সেট করা
        getWindow().setEnterTransition(new Fade());
    }
}

কোডের ব্যাখ্যা:

  • Slide() এবং Fade(): Transition এর ধরন। Slide Transition এ UI উপাদান স্ক্রিনে স্লাইড করে, এবং Fade Transition এ UI উপাদান ধীরে ধীরে দৃশ্যমান বা অদৃশ্য হয়।
  • getWindow().setExitTransition() এবং getWindow().setEnterTransition(): Activity এর জন্য Exit এবং Enter Transition সেট করা হয়েছে।

MotionLayout ব্যবহার করে Advanced Animation

MotionLayout হল ConstraintLayout এর উপর ভিত্তি করে তৈরি একটি লেআউট, যা UI উপাদানগুলোর অ্যানিমেশন এবং স্থানান্তর ম্যানেজ করতে সাহায্য করে। এটি Material Design এর সাথে সামঞ্জস্য রেখে অ্যানিমেশন তৈরি করার জন্য ব্যবহৃত হয়।

MotionLayout উদাহরণ:

  1. MotionLayout এর XML তৈরি:
<androidx.constraintlayout.motion.widget.MotionLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/motionLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ImageView
        android:id="@+id/imageView"
        android:layout_width="100dp"
        android:layout_height="100dp"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintStart_toStartOf="parent"/>

</androidx.constraintlayout.motion.widget.MotionLayout>
  1. MotionScene ফাইল তৈরি:
<MotionScene xmlns:android="http://schemas.android.com/apk/res/android">
    <Transition
        app:constraintSetStart="@id/start"
        app:constraintSetEnd="@id/end"
        app:duration="1000">
        <OnSwipe
            app:dragDirection="dragUp"
            app:touchAnchorId="@id/imageView"
            app:touchAnchorSide="bottom"/>
    </Transition>

    <ConstraintSet android:id="@+id/start">
        <Constraint
            android:id="@id/imageView"
            app:layout_constraintTop_toTopOf="parent"/>
    </ConstraintSet>

    <ConstraintSet android:id="@+id/end">
        <Constraint
            android:id="@id/imageView"
            app:layout_constraintBottom_toBottomOf="parent"/>
    </ConstraintSet>
</MotionScene>

উপসংহার

Android অ্যাপ্লিকেশনে Animations এবং Transitions ব্যবহার করে UI কে আরও ইন্টারঅ্যাকটিভ এবং ব্যবহারবান্ধব করা যায়। এগুলো ব্যবহারকারীর ইন্টারফেস এবং অ্যাপ্লিকেশনের কার্যকারিতা উন্নত করতে সাহায্য করে। Material Design এর নীতিমালা অনুসরণ করে অ্যানিমেশন এবং ট্রানজিশন তৈরি করলে, ব্যবহারকারীর অভিজ্ঞতা আরও উন্নত এবং আকর্ষণীয় হয়।

Content added By
Promotion
NEW SATT AI এখন আপনাকে সাহায্য করতে পারে।

Are you sure to start over?

Loading...